package com.bluezone.dec.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bluezone.dec.common.CacheConstant;
import com.bluezone.dec.common.SystemConstant;
import com.bluezone.dec.configuration.AppConfig;
import com.bluezone.dec.system.service.EnterpriseService;
import com.bluezone.dec.system.service.MajorHazardSourceStatisticsService;


import com.bluezone.dec.utils.TimeTransferUtils;
import com.google.common.base.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @Description 重大危险源统计service实现
 * @Author chenzhaoming
 * @CreateDate 2018/11/6 11:36
 * @Company 浙江航天恒嘉数据科技有限公司
 */
@Service
public class MajorHazardSourceStatisticsServiceImpl implements MajorHazardSourceStatisticsService {

    @Autowired
    private AppConfig appConfig;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private EnterpriseService enterpriseService;

    /**
     * 重大危险源标题卡片数据统计
     *
     * @return
     */
    @Override
    public Map<String, Object> majorHazard() {
        if (!stringRedisTemplate.hasKey(CacheConstant.MAJOR_DANGER_TITLE)) {
            int deviceNoteDetect = 0;     //设施未定期检查企业数量统计
            int entAccident = 0;        //近三年是否发生事故
            JSONArray enterpriseSecurityList = enterpriseService.getEnterpriseInfo(CacheConstant.ENTERPRISE_SECURITY);
            for (int i = 0; i < enterpriseSecurityList.size(); i++) {
                /*获取每个企业的重大危险源信息列表*/
                List<JSONObject> importantDangerInfoList = Optional.ofNullable(enterpriseSecurityList.getJSONObject(i).getJSONObject(SystemConstant.SECURITY))
                        .map(security -> security.getJSONObject("dangerChemicalsIndustryInfo"))
                        .map(danger -> danger.getJSONArray("importantDangerInfoList").toJavaList(JSONObject.class))
                        .orElse(new ArrayList<>());
                /*判断三年内是否发生过事故*/
                long accidentAmount = importantDangerInfoList.stream().filter(importantDangerInfo -> {
                    Boolean accident = importantDangerInfo.getBoolean("yearThreeAccident");
                    return null != accident && accident;
                }).count();
                if (accidentAmount > 0) {
                    entAccident += 1;
                }
                /*判断设施是否定期检查*/
                long regularInspectionAmount = importantDangerInfoList.stream().filter(importantDangerInfo -> {
                    Boolean regularInspection = importantDangerInfo.getBoolean("regularInspection");
                    return null != regularInspection && !regularInspection;
                }).count();
                if (regularInspectionAmount > 0) {
                    deviceNoteDetect += 1;
                }
            }
            Map<String, Object> majorHazard = new HashMap<>();
            majorHazard.put("majorDangerEntNum", enterpriseService.dangerEnterprise().size());
            majorHazard.put("majorDangerNum", enterpriseService.importantDangerInfoList().size());
            majorHazard.put("deviceNoexamNum", deviceNoteDetect);
            majorHazard.put("entAccident", entAccident);
            stringRedisTemplate.opsForValue().set(CacheConstant.MAJOR_DANGER_TITLE, JSON.toJSONString(majorHazard),
                    appConfig.getChartDataCacheTime(), TimeUnit.SECONDS);
        }
        String value = stringRedisTemplate.opsForValue().get(CacheConstant.MAJOR_DANGER_TITLE);
        return (Map<String, Object>) JSON.parseObject(value, Map.class);
    }

    /**
     * 重大危险源企业规模情况统计
     *
     * @return
     */
    @Override
    public Map<String, Object> scaleLevel() {
        if (!stringRedisTemplate.hasKey(CacheConstant.MAJOR_DANGER_SCALE)) {
            /*获取重大危险源企业的企业危险信息*/
            List<JSONObject> dangerEnterpriseList = enterpriseService.dangerEnterprise();
            List<JSONObject> baseEnterpriseListList = enterpriseService.getEnterpriseInfo(CacheConstant.ENTERPRISE_BASE).toJavaList(JSONObject.class);
            /*获取企业规模等级*/
            List<String> scaleSet = enterpriseService.getLevel(SystemConstant.SCALE);
            List<Map<String, Object>> scaleList = new ArrayList<>();
            for (String scale : scaleSet) {
                Map<String, Object> scaleMap = new HashMap<>();
                long total = dangerEnterpriseList.stream().filter(dangerEnterprise -> {
                    String creditCode = dangerEnterprise.getString(SystemConstant.ENTERPRISE_CODE);
                    String scaleValue = "";
                    for (JSONObject baseEnterprise : baseEnterpriseListList) {
                        if (creditCode.equals(baseEnterprise.getString(SystemConstant.ENTERPRISE_CODE))) {
                            scaleValue = Optional.ofNullable(baseEnterprise.getJSONObject(SystemConstant.BASE))
                                    .map(base -> base.getString(SystemConstant.SCALE))
                                    .orElse("");
                        }
                    }
                    return scale.equals(scaleValue);
                }).count();
                scaleMap.put(SystemConstant.NAME, scale);
                scaleMap.put(SystemConstant.VALUE, total);
                scaleList.add(scaleMap);
            }
            Map<String, Object> scale = new HashMap<>();
            scale.put(SystemConstant.NAME, "重大危险源企业规模情况");
            scale.put(SystemConstant.VALUE, scaleList);
            stringRedisTemplate.opsForValue().set
                    (CacheConstant.MAJOR_DANGER_SCALE, JSON.toJSONString(scale), appConfig.getChartDataCacheTime(), TimeUnit.SECONDS);
        }
        String result = stringRedisTemplate.opsForValue().get(CacheConstant.MAJOR_DANGER_SCALE);
        return (Map<String, Object>) JSON.parseObject(result, Map.class);
    }

    /**
     * 重大危险源等级企业数量分布统计
     *
     * @return
     */
    @Override
    public Map<String, Object> dangerLevelEnterprise() {
        if(!stringRedisTemplate.hasKey(CacheConstant.MAJOR_DANGER_ENTERPRISE)){
            /*获取全部企业安全信息*/
            JSONArray enterpriseSecurityList = enterpriseService.getEnterpriseInfo(CacheConstant.ENTERPRISE_SECURITY);
            List<String> dangerLevelList = enterpriseService.getType(SystemConstant.DANGER_LEVEL);
            List<Map<String, Object>> dangerLevelAmount = new ArrayList<>();
            /*遍历重大危险源等级*/
            for (String dangerLevel : dangerLevelList) {
                Map<String, Object> dangerLevelMap = new HashMap<>();
                int total = 0;
                for (int i = 0; i < enterpriseSecurityList.size(); i++) {
                    /*首先获取每一个企业重大危险源信息列表*/
                    List<JSONObject> importantDangerInfoList = Optional.ofNullable(enterpriseSecurityList.getJSONObject(i).getJSONObject(SystemConstant.SECURITY))
                            .map(security -> security.getJSONObject("dangerChemicalsIndustryInfo"))
                            .map(danger -> danger.getJSONArray("importantDangerInfoList").toJavaList(JSONObject.class))
                            .orElse(new ArrayList<>());
                    /*过滤重大危险源信息列表的重大危险源等级，*/
                    long amount = importantDangerInfoList.stream().filter(importantDanger ->
                            dangerLevel.equals(importantDanger.getString(SystemConstant.DANGER_LEVEL))).count();
                    /*如果企业涉及当前循环的重大危险源等级，则重大危险源等级企业数量分布+1*/
                    if (amount > 0) {
                        total += 1;
                    }
                }
                dangerLevelMap.put(SystemConstant.NAME, dangerLevel);
                dangerLevelMap.put(SystemConstant.VALUE, total);
                dangerLevelAmount.add(dangerLevelMap);
            }

            Map<String, Object> dangerLevel = new HashMap<>();
            dangerLevel.put(SystemConstant.NAME, "重大危险源等级企业数量分布");
            dangerLevel.put(SystemConstant.VALUE, dangerLevelAmount);
            stringRedisTemplate.opsForValue().set(CacheConstant.MAJOR_DANGER_ENTERPRISE,JSON.toJSONString(dangerLevel),appConfig.getChartDataCacheTime(),TimeUnit.SECONDS);
        }
        String result = stringRedisTemplate.opsForValue().get(CacheConstant.MAJOR_DANGER_ENTERPRISE);
        return (Map<String, Object>)JSON.parseObject(result,Map.class);
    }

    /**
     * 重大危险源等级分布
     *
     * @return
     */
    @Override
    public Map<String, Object> dangerLevelStatistics() {
        if(!stringRedisTemplate.hasKey(CacheConstant.MAJOR_DANGER_LEVEL)){
            /*获取所有重大危险源等级*/
            List<String> dangerLevelList = enterpriseService.getType(SystemConstant.DANGER_LEVEL);
            /*获取全部重大危险源信息列表*/
            List<JSONObject> importantDangerInfoList = enterpriseService.importantDangerInfoList();
            List<Map<String, Object>> dangerLevelAmount = new ArrayList<>();
            for (String dangerLevel : dangerLevelList) {
                Map<String, Object> dangerLevelMap = new HashMap<>();
                long total = importantDangerInfoList.stream().filter(importantDanger ->
                        dangerLevel.equals(importantDanger.getString(SystemConstant.DANGER_LEVEL))).count();
                dangerLevelMap.put(SystemConstant.NAME, dangerLevel);
                dangerLevelMap.put(SystemConstant.VALUE, total);
                dangerLevelAmount.add(dangerLevelMap);
            }
            Map<String, Object> dangerLevel = new HashMap<>();
            dangerLevel.put(SystemConstant.NAME, "重大危险源等级分布");
            dangerLevel.put(SystemConstant.VALUE, dangerLevelAmount);
            stringRedisTemplate.opsForValue().set(CacheConstant.MAJOR_DANGER_LEVEL,JSON.toJSONString(dangerLevel),appConfig.getChartDataCacheTime(),TimeUnit.SECONDS);
        }
        String result = stringRedisTemplate.opsForValue().get(CacheConstant.MAJOR_DANGER_LEVEL);
        return (Map<String, Object>)JSON.parseObject(result,Map.class);
    }

    /**
     * 重大危险源行业类别分布统计
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> industry() {
        if (!stringRedisTemplate.hasKey(CacheConstant.MAJOR_DANGER_INDUSTRY)) {
            /*获取所有的重大危险源企业*/
            List<JSONObject> dangerEnterpriseList = enterpriseService.dangerEnterprise();
            List<JSONObject> baseEnterpriseListList = enterpriseService.getEnterpriseInfo(CacheConstant.ENTERPRISE_BASE).toJavaList(JSONObject.class);
            List<Map<String, Object>> industryTypeList = new ArrayList<>();
            List<String> industryType = enterpriseService.getLevel(SystemConstant.DANGEROUS_TYPE);
            for (String industry : industryType) {
                Map<String, Object> industryTypeMap = new HashMap<>();
                int total = 0;
                for (JSONObject dangerEnterprise : dangerEnterpriseList) {
                    /*遍历企重大危险源企业列表，判断该企业的行业类型*/
                    if (industry.equals(enterpriseService.getIndustryType(
                            dangerEnterprise.getString(SystemConstant.ENTERPRISE_CODE), SystemConstant.DANGEROUS_TYPE, baseEnterpriseListList))) {
                        total += 1;
                    }
                }
                industryTypeMap.put(SystemConstant.NAME, industry);
                industryTypeMap.put(SystemConstant.VALUE, total);
                industryTypeList.add(industryTypeMap);
            }
            stringRedisTemplate.opsForValue().set(CacheConstant.MAJOR_DANGER_INDUSTRY, JSON.toJSONString(industryTypeList), appConfig.getChartDataCacheTime(), TimeUnit.SECONDS);
        }
        String result = stringRedisTemplate.opsForValue().get(CacheConstant.MAJOR_DANGER_INDUSTRY);
        return (List<Map<String, Object>>) JSON.parseObject(result, List.class);
    }

    /**
     * 重大危险源活动类型统计
     * 重大危险源可能引发事故的类型统计
     *
     * @return
     */
    public List<Map<String, Object>> getType(String type,String cacheConstant) {
        if (!stringRedisTemplate.hasKey(cacheConstant)) {
            /*获取全部的重大危险源信息列表*/
            List<JSONObject> importantDangerInfoList = enterpriseService.importantDangerInfoList();
            List<String> typeList = enterpriseService.getType(type);
            List<Map<String, Object>> typeAmount = new ArrayList<>();
            for (String activity : typeList) {
                Map<String, Object> typeMap = new HashMap<>();
                long total = importantDangerInfoList.stream().filter(dangerInfo -> activity.equals(dangerInfo.getString(type))).count();
                typeMap.put(SystemConstant.NAME, activity);
                typeMap.put(SystemConstant.VALUE, total);
                typeAmount.add(typeMap);
            }
            stringRedisTemplate.opsForValue().set(cacheConstant, JSON.toJSONString(typeAmount), appConfig.getChartDataCacheTime(), TimeUnit.SECONDS);
        }
        String result = stringRedisTemplate.opsForValue().get(cacheConstant);
        return (List<Map<String, Object>>) JSON.parseObject(result, List.class);
    }

    /**
     * 重大危险源活动类型增长情况统计
     * 重大危险源可能引发事故的类型增长情况统计
     *
     * @return
     */
    @Override
    public Map<String, Object> getMajorGrowthAnalysis(String analysisType,String cacheConstant) {
        if (!stringRedisTemplate.hasKey(cacheConstant)) {
            /*获取全部的重大危险源信息列表*/
            List<JSONObject> importantDangerInfoList = enterpriseService.importantDangerInfoList();
            /*获取所有可能引发的事故类型.获取重大危险源级别的集合*/
            List<String> accidentType = enterpriseService.getType(analysisType);
            /*获取最近一年的所有月份*/
            List<String> dateList = TimeTransferUtils.getDayList();
            List<Map<String, Object>> accidentList = new ArrayList<>();
            for (String accident : accidentType) {
                Map<String, Object> accidentMap = new HashMap<>();
                List<Object> totalList = new ArrayList<>();
                for (String date : dateList) {
                    long total = importantDangerInfoList.stream().filter(dangerInfo -> {
                        String dangerSourceCreateDate = dangerInfo.getString("dangerSourceCreateDate");
                        String createDate = "";
                        if (!Strings.isNullOrEmpty(dangerSourceCreateDate)) {
                            createDate = dangerSourceCreateDate.substring(0, 7);
                        }
                        return accident.equals(dangerInfo.getString(analysisType)) && date.equals(createDate);
                    }).count();
                    totalList.add(total);
                }
                accidentMap.put(SystemConstant.NAME, accident);
                accidentMap.put(SystemConstant.VALUE, totalList);
                accidentList.add(accidentMap);
            }
            Map<String, Object> analysisMap = new HashMap<>();
            analysisMap.put("dateList", dateList);
            analysisMap.put(SystemConstant.VALUE, accidentList);
            stringRedisTemplate.opsForValue().set(cacheConstant, JSON.toJSONString(analysisMap), appConfig.getChartDataCacheTime(), TimeUnit.SECONDS);
        }
        String result = stringRedisTemplate.opsForValue().get(cacheConstant);
        return (Map<String, Object>) JSON.parseObject(result, Map.class);
    }
}
